﻿using YooAssetsSystem.Fsm;
using UnityEngine;
using YooAsset;

namespace YooAssetsSystem.Patch
{
    public partial class PatchSeveice
    {
        
    }
    
    public partial class PatchSeveice
    {
        /// 补丁更新参数
        public class PatchConfig
        {
            public EPlayMode playMode; //资源初始化模式
            public bool isDefaultPackage; //是否设置为默认包
            public string appVersion; //应用版本
            public string updateResUrl; //更新路径
            public string[] loadTags = new string[0]; //下载指定tag 默认:全部下载
            public int multiMaxNumber = 10; //同时下载数
            public int failedTryAgain = 3; //失败重试次数
            public bool isCustomizeUrl = false; //是否自定义url
        }

        public PatchEvent Event { get; private set; } = new PatchEvent();
        public string Package { get; private set; }
        public PatchConfig Config { get; private set; }

        private StateMachine<PatchNodeData> fsm;

        public PatchSeveice(string package, PatchConfig config)
        {
            if(!YooAssets.Initialized)
                YooAssets.Initialize();
            
            Package = package;
            Config = config;
            var nodeData = new PatchNodeData(GetHostServerURL());
            fsm = new StateMachine<PatchNodeData>(this, nodeData);
            fsm.AddNode<ClearPackageAllCacheBundleFilesNode>();
            fsm.AddNode<PatchInitNode>();
            fsm.AddNode<UpdateVersionNode>();
            fsm.AddNode<UpdateManifestNode>();
            fsm.AddNode<CreateDownloadNode>();
            fsm.AddNode<DownloadFilesNode>();
            fsm.AddNode<PatchDoneNode>();

            Event.PatchDoneEvent += PatchDoneEvent;
            Event.UpdateFailedEvent += UpdateFailedEvent;
        }

        /// <summary>
        /// 启动更新
        /// </summary>
        public void Run()
        {
            Stop();
            fsm.Run<PatchInitNode>();
        }

        /// <summary>
        /// 暂停下载
        /// </summary>
        public void Pause()
        {
            fsm.ShareData.pauseDownload = true;
        }
        
        /// <summary>
        /// 恢复下载
        /// </summary>
        public void Resume()
        {
            fsm.ShareData.pauseDownload = false;
        }

        /// <summary>
        /// 停止更新/下载
        /// </summary>
        public void Stop()
        {
            if (fsm.IsRunning())
            {
                fsm.Stop();
                Debug.Log($"{GetType().FullName} 更新结束");
            }
        }

        public void Update()
        {
            fsm.Update();
        }

        #region URL
        
        /// <summary>
        /// 获取资源服务器地址
        /// </summary>
        public string GetHostServerURL()
        {
            if(Config.isCustomizeUrl)
            {
                return Config.updateResUrl;
            }
            string hostServerIP = Config.updateResUrl;
            string appVersion = Config.appVersion;
            
            if (Application.platform == RuntimePlatform.Android)
                return $"{hostServerIP}/Android/{Package}/{appVersion}";
            else if (Application.platform == RuntimePlatform.IPhonePlayer)
                return $"{hostServerIP}/IPhone/{Package}/{appVersion}";
            else if (Application.platform == RuntimePlatform.WebGLPlayer)
                return $"{hostServerIP}/WebGL/{Package}/{appVersion}";
            else
                return $"{hostServerIP}/PC/{Package}/{appVersion}";
        }
    
        /// <summary>
        /// 远端资源地址查询服务类
        /// </summary>
        public class RemoteServices : IRemoteServices
        {
            private readonly string _defaultHostServer;
            private readonly string _fallbackHostServer;
    
            public RemoteServices(string defaultHostServer, string fallbackHostServer)
            {
                _defaultHostServer = defaultHostServer;
                _fallbackHostServer = fallbackHostServer;
            }
            string IRemoteServices.GetRemoteMainURL(string fileName)
            {
                return $"{_defaultHostServer}/{fileName}";
            }
            string IRemoteServices.GetRemoteFallbackURL(string fileName)
            {
                return $"{_fallbackHostServer}/{fileName}";
            }
        }

        #endregion

        #region Event

        void PatchDoneEvent(string msg)
        {
            Debug.Log($"PatchManager:: PatchDoneEvent: {msg}");
            Stop();
        }
        
        private void UpdateFailedEvent(string obj)
        {
            Debug.LogError($"{Package}更新失败: {obj}");
        }

        #endregion
    }
}